package com.example.coursehub.course.entity;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

/**
 * 教学资料实体类
 * 改进了原有设计，添加了文件类型和大小字段
 */
@Getter
@Setter
@Entity
@Table(name = "material", schema = "courseHub")
@NoArgsConstructor
@AllArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public class Material {
    
    @Id
    @Column(name = "material_id", nullable = false, length = 100)
    private String materialId;

    @NotBlank(message = "资料名称不能为空")
    @Size(max = 100, message = "资料名称长度不能超过100个字符")
    @Column(name = "material_name", nullable = false, length = 100)
    private String materialName;

    @NotBlank(message = "资料路径不能为空")
    @Size(max = 255, message = "资料路径长度不能超过255个字符")
    @Column(name = "material_path", nullable = false, length = 255)
    private String materialPath;

    /**
     * 资料标签
     */
    @Size(max = 100, message = "资料标签长度不能超过100个字符")
    @Column(name = "material_label", length = 100)
    private String materialLabel;

    /**
     * 文件类型（扩展名）
     */
    @Column(name = "file_type", length = 20)
    private String fileType;

    /**
     * 文件大小（字节）
     */
    @Column(name = "file_size")
    private Long fileSize;

    /**
     * 资料描述
     */
    @Size(max = 500, message = "资料描述长度不能超过500个字符")
    @Column(name = "description", length = 500)
    private String description;

    /**
     * 资料状态：0-草稿，1-发布
     */
    @Column(name = "status", nullable = false)
    private Integer status = 1;

    /**
     * 上传者ID
     */
    @Column(name = "uploader_id", length = 100)
    private String uploaderId;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @JoinColumn(name = "course_id", nullable = false)
    private Course course;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @JoinColumn(name = "chapter_id", nullable = false)
    private Chapter chapter;

    @CreatedDate
    @Column(name = "created_at", nullable = false, updatable = false)
    private LocalDateTime createdAt;

    @LastModifiedDate
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;

    /**
     * 资料类型枚举
     */
    public enum MaterialType {
        DOCUMENT("文档"),
        VIDEO("视频"),
        AUDIO("音频"),
        IMAGE("图片"),
        ARCHIVE("压缩包"),
        OTHER("其他");

        private final String description;

        MaterialType(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }

        public static MaterialType fromFileExtension(String extension) {
            if (extension == null) return OTHER;
            
            String ext = extension.toLowerCase();
            if (ext.matches("pdf|doc|docx|txt|ppt|pptx|xls|xlsx")) {
                return DOCUMENT;
            } else if (ext.matches("mp4|avi|mov|wmv|flv|mkv")) {
                return VIDEO;
            } else if (ext.matches("mp3|wav|flac|aac")) {
                return AUDIO;
            } else if (ext.matches("jpg|jpeg|png|gif|bmp|svg")) {
                return IMAGE;
            } else if (ext.matches("zip|rar|7z|tar|gz")) {
                return ARCHIVE;
            }
            return OTHER;
        }
    }

    /**
     * 资料状态枚举
     */
    public enum MaterialStatus {
        DRAFT(0, "草稿"),
        PUBLISHED(1, "已发布");

        private final Integer code;
        private final String description;

        MaterialStatus(Integer code, String description) {
            this.code = code;
            this.description = description;
        }

        public Integer getCode() {
            return code;
        }

        public String getDescription() {
            return description;
        }
    }
}